﻿using System.Security.Cryptography;
using System.Text;
using System.Management;

namespace Api_Core_Spider.Services
{
    /// <summary>
    /// 机器码生成器实现，通过硬件信息生成唯一机器码
    /// </summary>
    public class MachineCodeGenerator : IMachineCodeGenerator
    {
        /// <summary>
        ///根据设备信息， 生成机器码
        /// </summary>
        /// <returns>机器码字符串</returns>
        public string GenerateMachineCode()
        {
            try
            {
                // 收集多种硬件信息
                string cpuInfo = GetCpuInfo();
                string diskInfo = GetDiskInfo();
                string macAddress = GetMacAddress();

                // 组合硬件信息
                string hardwareInfo = $"{cpuInfo}{diskInfo}{macAddress}";

                // 使用SHA256生成哈希
                using (SHA256 sha256 = SHA256.Create())
                {
                    byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(hardwareInfo));

                    // 转换为Base64并替换不适合URL的字符
                    string machineCode = Convert.ToBase64String(hashBytes)
                        .Replace('+', '-')
                        .Replace('/', '_')
                        .TrimEnd('=');

                    return machineCode;
                }
            }
            catch (Exception ex)
            {
                // 发生异常时生成一个基于GUID的临时机器码
                Console.WriteLine($"生成机器码时出错: {ex.Message}");
                return Guid.NewGuid().ToString("N");
            }
        }

        /// <summary>
        /// 获取当前机器信息
        /// </summary>
        /// <returns>机器信息对象</returns>
        public Models.MachineInfo GetMachineInfo()
        {
            return new Models.MachineInfo
            {
                MachineCode = GenerateMachineCode(),
                CpuInfo = GetCpuInfo(),
                DiskInfo = GetDiskInfo(),
                NetworkInfo = GetMacAddress(),
                OsInfo = GetOsInfo(),
                AppVersion = System.Reflection.Assembly.GetEntryAssembly()?
                    .GetName().Version?.ToString() ?? "1.0.0"
            };
        }
        /// <summary>
        /// 获取CPU信息
        /// </summary>
        /// <returns></returns>
        private string GetCpuInfo()
        {
            try
            {
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor"))
                {
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        return obj["ProcessorId"]?.ToString() ?? "";
                    }
                }
                return "";
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// 获取硬盘信息
        /// </summary>
        /// <returns></returns>
        private string GetDiskInfo()
        {
            try
            {
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_DiskDrive WHERE Index = 0"))
                {
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        return obj["SerialNumber"]?.ToString() ?? "";
                    }
                }
                return "";
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// 获取MAC地址
        /// </summary>
        /// <returns></returns>
        private string GetMacAddress()
        {
            try
            {
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"))
                {
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        string mac = obj["MACAddress"]?.ToString() ?? "";
                        if (!string.IsNullOrEmpty(mac))
                            return mac.Replace(":", "");
                    }
                }
                return "";
            }
            catch
            {
                return "";
            }
        }

        private string GetOsInfo()
        {
            try
            {
                return System.Environment.OSVersion.ToString();
            }
            catch
            {
                return "";
            }
        }
    }
}